package com.plian.system.service.qg.evaluate.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.plian.Tools.*;
import com.plian.Tools.pagedata.PageData;
import com.plian.system.cache.UserCache;
import com.plian.system.common.status.CheckStatus;
import com.plian.system.constant.sys.FormStatusConstant;
import com.plian.system.constant.sys.FormTypeConstant;
import com.plian.system.constant.yth.YthConstant;
import com.plian.system.entity.qg.evaluate.EvaluateReform;
import com.plian.system.entity.sys.ApprovalMessage;
import com.plian.system.mapper.qg.evaluate.EvaluateReformMapper;
import com.plian.system.mybatis.base.BaseFlowService;
import com.plian.system.mybatis.base.BaseServiceImpl;
import com.plian.system.mybatis.support.Condition;
import com.plian.system.service.qg.evaluate.IEvaluateReformService;
import com.plian.system.service.sys.message.IApprovalMessageService;
import com.plian.system.service.sys.orgzation.IOrgService;
import com.plian.system.service.sys.user.ISysUserService;
import com.plian.system.service.yth.IEvaluationPlanService;
import com.plian.system.vo.qg.evaluate.EvaluateReformVO;
import com.plian.system.vo.yth.YthResult;
import com.plian.system.wrapper.qg.evaluate.EvaluateReformWrapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

import static com.plian.system.constant.sys.ApprovalMessageTypeConstant.INVESTMENT_EXECUTION;
import static com.plian.system.constant.sys.ApprovalMessageTypeConstant.KT_TYPE;
import static com.plian.system.constant.sys.FormStatusConstant.UNREVIEWED;

/**
 * @author lwb
 * @create 2023-02-20
 * @description
 */
@Slf4j
@Service
@AllArgsConstructor
public class IEvaluateReformServiceImpl extends BaseServiceImpl<EvaluateReformMapper, EvaluateReform> implements IEvaluateReformService, BaseFlowService {

    private EvaluateReformWrapper evaluateReformWrapper;

    private IEvaluationPlanService evaluationPlanService;

    private IOrgService orgService;

    private ISysUserService userService;

    private IApprovalMessageService approvalMessageService;
    @Override
    public EvaluateReformVO getDetailObj(EvaluateReform evaluateReform) {
        EvaluateReform detail = getOne(Condition.getQueryWrapper(evaluateReform));
        EvaluateReformVO negativeInvestmentVO = evaluateReformWrapper.entityToVO(detail);
        return negativeInvestmentVO;
    }

    @Override
    public boolean saveOrUpdate(EvaluateReform evaluateReform) {
        if (!Optional.ofNullable(evaluateReform.getStatus()).isPresent()) {
            evaluateReform.setStatus(FormStatusConstant.UNREVIEWED);
        }
        if (!Optional.ofNullable(evaluateReform.getId()).isPresent()) {
            evaluateReform.setFormType(String.valueOf(FormTypeConstant.QG_EVALUATE_REFORM));
        }
        return super.saveOrUpdate(evaluateReform);
    }

    @Override
    @Transactional(rollbackFor=RuntimeException.class)
    public boolean submit(EvaluateReform evaluateReform) {
        boolean result = saveOrUpdate(evaluateReform);
        return result;
    }

    @Override
    public HashMap<String,Object> commit(String id) {
        handleStatus(Long.valueOf(id), FormStatusConstant.FLOW, null);

        //将需要提交的流程变量返回，用于工作流侧
        return new HashMap<String,Object>();
    }

    @Override
    public Boolean finish(String id) {
        return handleStatus(Long.valueOf(id), FormStatusConstant.FINISH,"审批通过");
    }

    @Override
    public Boolean reject(String id, int formState,String comment) {
        return handleStatus(Long.valueOf(id), formState,comment);
    }

    @Override
    public List<PageData> findByIds(List<String> formIds) {
        LambdaQueryWrapper<EvaluateReform> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(EvaluateReform::getId, Func.toLongList(StringUtils.join(formIds, StringPool.COMMA)));
        List<EvaluateReform> evaluateReforms = list(queryWrapper);
        List<EvaluateReformVO> evaluateReformVOS = evaluateReformWrapper.entityToVO(evaluateReforms);
        List<PageData> pageDataList = new ArrayList<>();
        try{
            if (CollectionUtil.isNotEmpty(evaluateReformVOS)){
                for (EvaluateReformVO vo : evaluateReformVOS){
                    PageData pd = new PageData();
                    pd.put("id", vo.getId());
                    pd.put("UNITNAME", vo.getEnterpriseNameId());
                    pd.put("APPLICANTNAME", vo.getCreateUserName());
                    pd.put("applicantId", vo.getCreateUser());
                    pd.put("applyOrganizationId", vo.getEnterpriseNameId());
                    pd.put("formType", FormTypeConstant.QG_EVALUATE_REFORM);
                    pd.put("orgName", vo.getEnterpriseNameId());

                    pageDataList.add(pd);
                }
            }

            return pageDataList;
        } catch (Exception e) {
            log.error(ExceptionUtils.getFullStackTrace(e));
        }
        return pageDataList;
    }

    @Override
    public List<Integer> getFormType() {
        return Arrays.asList(FormTypeConstant.QG_EVALUATE_REFORM);
    }

    @Override
    public void goBackToStash(String formId) {
        handleStatus(Long.valueOf(formId), UNREVIEWED, null);
    }

    /**
     * 统一处理状态机事件方法
     *
     * @param id          主键
     * @param updateStatus  更新状态
     * @return boolean
     */
    private Boolean handleStatus(Long id, int updateStatus,String comment) {
        try {
            EvaluateReform evaluateReform = getById(id);
            /**
             * 设置审批人和审批时间
             */
            if (updateStatus == FormStatusConstant.FINISH){
                evaluateReform.setApprovedUser(TokenUtil.getTokenUserId());
                Date now = DateUtil.now();
                evaluateReform.setApprovedTime(now);
            }
            if (StringUtil.isNotBlank(evaluateReform.getDataSource()) &&StringUtil.isNotBlank(evaluateReform.getDataSourceId())){
                if (updateStatus == FormStatusConstant.FINISH || updateStatus == FormStatusConstant.REJECT){
                    ApprovalMessage approvalMessage = new ApprovalMessage();
                    approvalMessage.setDataSourceId(evaluateReform.getDataSourceId());
                    approvalMessage.setType(INVESTMENT_EXECUTION);
                    approvalMessage.setOpinion(comment);
                    approvalMessage.setIsApprove(updateStatus == FormStatusConstant.FINISH ? 2 : 1);
                    approvalMessage.setIsSend(1);
                    approvalMessage.setDataSourceType(KT_TYPE);
                    if (evaluateReform.getDataSource().equals(YthConstant.DATA_NINGBO)) {
                        approvalMessage.setDataSourceType(YthConstant.DATA_NINGBO);
                        approvalMessage.setFilingUserName(UserCache.userIdToName(TokenUtil.getTokenUserId()));
                        approvalMessage.setFormType(Integer.parseInt(evaluateReform.getFormType()));
                        approvalMessage.setFilingCode(evaluateReform.getCode());
                    }
                    approvalMessageService.save(approvalMessage);
                }
            }

            evaluateReform.setStatus(updateStatus);
            updateById(evaluateReform);
            return true;
        } catch (Exception e) {
            log.error(ExceptionUtils.getFullStackTrace(e));
            return false;
        }
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public String saveEvaluateReform(String data){
        YthResult ythResult = new YthResult();
        //成功的id集合
        List<String> successIds = new ArrayList<>();
        //失败的id集合
        List<String> failIds = new ArrayList<>();
        //失败的原因
        List<String> failReasons = new ArrayList<>();
        //将json字符串转换成list
        List<EvaluateReform> dataList = JSON.parseArray(data, EvaluateReform.class);
        if (CollectionUtil.isNotEmpty(dataList)){
            //根据datasourceIds 查询出所有的数据
            List<EvaluateReform> list = list(new LambdaQueryWrapper<EvaluateReform>().in(EvaluateReform::getDataSourceId, dataList.stream().map(EvaluateReform::getDataSourceId).toArray()));
            //如果数据库中有数据，就更新，没有就新增
            for (EvaluateReform entity:dataList){
                //id重复略过
                if (CollectionUtil.isNotEmpty(list)){
                    List<String> olIds = list.stream().map(EvaluateReform::getDataSourceId).collect(Collectors.toList());
                    String dataSourceId = entity.getDataSourceId();
                    //判断数据库中是否有数据
                    if (olIds.contains(dataSourceId)){
                        for (EvaluateReform oldEntity:list){
                            if (dataSourceId.equals(oldEntity.getDataSourceId())){
                                //判断status是否为0，如果是0，就更新，不是0，就不更新
                                if (CheckStatus.checkCode(oldEntity.getStatus())){
                                    successIds.add(dataSourceId);
                                    entity.setId(oldEntity.getId());
                                    entity.setDataSource(YthConstant.DATA_NINGBO);
                                    submit(entity);
                                    list.remove(oldEntity);
                                    break;
                                }else {
                                    failIds.add(dataSourceId);
                                    failReasons.add("dataSourceId:"+dataSourceId+"数据已提交且已经在流程中，无法更新");
                                    break;
                                }
                            }
                        }
                    }else {
                        //如果数据库中没有数据，就新增
                        entity.setDataSource(YthConstant.DATA_NINGBO);
                        submit(entity);
                        successIds.add(entity.getDataSourceId());
                    }
                }else {
                    //如果数据库中没有数据，就新增
                    entity.setDataSource(YthConstant.DATA_NINGBO);
                    submit(entity);
                    successIds.add(entity.getDataSourceId());
                }
            }
        } else {
            failReasons.add("数据为空");
        }
        ythResult.setSuccessIds(successIds);
        ythResult.setFailIds(failIds);
        ythResult.setFailReason(StringUtils.join(failReasons, ";"));
        //ythResult转换成json字符串
        return JSON.toJSONString(ythResult);
    }


}
